package com.luck.easyfoodbatch.callback;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.text.TextUtils;
import android.widget.Toast;

import com.apkfuns.logutils.LogUtils;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.luck.easyfoodbatch.MainActivity;
import com.luck.easyfoodbatch.mvp.model.UserModel;
import com.luck.easyfoodbatch.ui.AnnualFeeActivity;
import com.luck.easyfoodbatch.ui.LoginActivity;
import com.luck.easyfoodbatch.ui.PaymentBondActivity;
import com.luck.easyfoodbatch.util.Tools;
import com.lzy.okhttputils.OkHttpUtils;

import org.json.JSONObject;

import java.lang.reflect.Type;
import java.util.List;

import okhttp3.Response;

/**
 * ================================================
 * 作    者：luck
 * 版    本：1.0
 * 创建日期：2016/1/14
 * 描    述：默认将返回的数据解析成需要的Bean,可以是 BaseBean，String，List，Map
 * 修订历史：
 * ================================================
 */
public abstract class JsonCallback<T> extends EncryptCallback<T> {
    private final String TAG = "接口返回原始Json数据------->";
    private Class<T> clazz;
    private Type type;
    // private Gson gson = new Gson();
    private Gson gson = new GsonBuilder().serializeNulls().create();
    /**
     * status : 1
     * authToken :
     * data : []
     * msg : 发布成功
     */

    private int status;
    private String authToken;
    private String msg;
    private List<?> data;
    private Context mContext;

    public JsonCallback(Context mContext, Class<T> clazz) {
        this.clazz = clazz;
        this.mContext = mContext;
    }

    public JsonCallback(Context mContext, Type type) {
        this.type = type;
        this.mContext = mContext;
    }

    //该方法是子线程处理，不能做ui相关的工作
    @Override
    public T parseNetworkResponse(Response response) throws Exception {
        String responseData = response.body().string();
        if (TextUtils.isEmpty(responseData)) return null;
        LogUtils.json(responseData);
        /**
         * 一般来说，服务器返回的响应码都包含 code，msg，data 三部分，在此根据自己的业务需要完成相应的逻辑判断
         * 以下只是一个示例，具体业务具体实现
         */
        JSONObject jsonObject = new JSONObject(responseData);
        final String msg = jsonObject.optString("msg", "");
        final int code = jsonObject.optInt("status", 0);
        String data = jsonObject.optString("data", "");
        String authToken = jsonObject.optString("authToken", "");

        switch (code) {
            case 0:
            case 1:
                /**
                 * code = 0 代表成功，默认实现了Gson解析成相应的实体Bean返回，可以自己替换成fastjson等
                 * 对于返回参数，先支持 String，然后优先支持class类型的字节码，最后支持type类型的参数
                 */
                if (clazz == String.class)
                    return (T) data;
                if (clazz != null) {
                    // 转对象
                    T fromJson = null;
//                    // 防止 data字段 本身是对象，无数据又为空数组 报异常的问题
                    if (!Tools.isNull(data) && data.equals("[]")) {
                        JSONObject object = new JSONObject();
                        object.put("status", code);
                        object.put("authToken", authToken);
                        object.put("msg", msg);
                        fromJson = gson.fromJson(object.toString(), clazz);
                    } else {
                        // 解决后台 不能把空对象返回的问题  坑爹...
                        if (clazz == UserModel.class) {
                            JSONObject object = new JSONObject(data);
                            String default_address = object.optString("default_address");
                            String default_house = object.optString("default_house");
                            if (!Tools.isNull(default_address) && default_address.equals("[]")) {
                                object.remove("default_address");
                            }
                            if (!Tools.isNull(default_house) && default_house.equals("[]")) {
                                object.remove("default_house");
                            }
                            JSONObject object1 = new JSONObject();
                            object1.put("status", code);
                            object1.put("authToken", authToken);
                            object1.put("msg", msg);
                            object1.put("data", object);
                            fromJson = gson.fromJson(object1.toString(), clazz);
                        } else {
                            fromJson = gson.fromJson(responseData, clazz);
                        }
                    }
                    return fromJson;
                }
                if (type != null) {
                    // 转数组
                    data = jsonObject.optString("data", "");
                    return gson.fromJson(data, type);
                }
                break;
            case 100:
                Intent intent = new Intent();
                intent.setClass(mContext, LoginActivity.class);
                ((Activity) mContext).startActivity(intent);
                if (((Activity) mContext) instanceof MainActivity) {

                } else {
                    ((Activity) mContext).finish();
                }
                break;
            case 104:
                //比如：用户授权信息无效，在此实现相应的逻辑，弹出对话或者跳转到其他页面等,该抛出错误，会在onError中回调。
                throw new IllegalStateException("用户授权信息无效");

            case 105:
                // 要去交年费
                Intent intent1 = new Intent();
                intent1.setClass(mContext, AnnualFeeActivity.class);
                ((Activity) mContext).startActivity(intent1);
            case 106:
                // 要去交保证金
                Intent intent2 = new Intent();
                intent2.setClass(mContext, PaymentBondActivity.class);
                ((Activity) mContext).startActivity(intent2);
            case 300:
                //比如：其他乱七八糟的等，在此实现相应的逻辑，弹出对话或者跳转到其他页面等,该抛出错误，会在onError中回调。
                throw new IllegalStateException("其他乱七八糟的等");
            default:
                throw new IllegalStateException("错误代码：" + code + "，错误信息：" + msg);
        }
        //如果要更新UI，需要使用handler，可以如下方式实现，也可以自己写handler
        OkHttpUtils.getInstance().getDelivery().post(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(OkHttpUtils.getContext(), msg, Toast.LENGTH_SHORT).show();
            }
        });
        return null;
    }

    public int getStatus() {
        return status;
    }

    public void setStatus(int status) {
        this.status = status;
    }

    public String getAuthToken() {
        return authToken;
    }

    public void setAuthToken(String authToken) {
        this.authToken = authToken;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public List<?> getData() {
        return data;
    }

    public void setData(List<?> data) {
        this.data = data;
    }
}
